﻿/* ######################################## *\
 * ### Copyright (C) 2009 AJ Ravindiran ### *
\* ######################################## */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using AJRavindiran.Jolt.RuneScape.Models.Characters;

namespace AJRavindiran.Jolt.RuneScape.Network.Packets.Builders
{
    /// <summary>
    /// Represents a character update builder.
    /// </summary>
    public class CharacterUpdate : CharacterUpdateMasks
    {
        #region Methods
        /// <summary>
        /// Updates a specific character.
        /// </summary>
        /// <param name="character">The character to update.</param>
        public void Update(Character character)
        {
            if (character.GetUpdateFlags().DidMapRegionChange)
            {
                RuneScape.GetPacketManager().GetFrames().SendMapRegion(character);
            }

            character.GetStreamWriter().CreateFrameVarSizeShort(217).InitializeBitAccess();
            this.UpdateThisPlayerMovement(character);
        }

        /// <summary>
        /// Updates movement for other players within distance.
        /// </summary>
        public void UpdatePlayerMovement(Character character)
        {
            if (character.GetSprites().PrimarySprite == -1)
            {
                if (character.GetUpdateFlags().IsUpdateRequired())
                    character.GetStreamWriter().WriteBits(1, 1).WriteBits(2, 0);
                else
                    character.GetStreamWriter().WriteBits(1, 0);
            }
            else if (character.GetSprites().SecondarySprite == -1)
            {
                character.GetStreamWriter()
                    .WriteBits(1, 1)
                    .WriteBits(2, 1)
                    .WriteBits(3, character.GetSprites().PrimarySprite)
                    .WriteBits(1, character.GetUpdateFlags().IsUpdateRequired() ? 1 : 0);
            }
            else
            {
                character.GetStreamWriter()
                    .WriteBits(1, 1)
                    .WriteBits(2, 2)
                    .WriteBits(3, character.GetSprites().PrimarySprite)
                    .WriteBits(3, character.GetSprites().SecondarySprite)
                    .WriteBits(1, character.GetUpdateFlags().IsUpdateRequired() ? 1 : 0);
            }
        }

        /// <summary>
        /// Updates a selected player.
        /// </summary>
        public void UpdateThisPlayerMovement(Character character)
        {
            if (character.GetUpdateFlags().DidTeleport)
            {
                character.GetStreamWriter()
                    .WriteBits(1, 1)
                    .WriteBits(2, 3)
                    .WriteBits(7, character.GetLocation().GetLocalX(character.GetUpdateFlags().LastRegion))
                    .WriteBits(1, 1)
                    .WriteBits(2, character.GetLocation().Z)
                    .WriteBits(1, character.GetUpdateFlags().IsUpdateRequired() ? 1 : 0)
                    .WriteBits(7, character.GetLocation().GetLocalY(character.GetUpdateFlags().LastRegion));
            }
            else
            {
                if (character.GetSprites().PrimarySprite == -1)
                {
                    character.GetStreamWriter().WriteBits(1, character.GetUpdateFlags().IsUpdateRequired() ? 1 : 0);
                    if (character.GetUpdateFlags().IsUpdateRequired())
                    {
                        character.GetStreamWriter().WriteBits(2, 0);
                    }
                }
                else
                {
                    if (character.GetSprites().SecondarySprite != -1)
                    {
                        character.GetStreamWriter()
                            .WriteBits(1, 1)
                            .WriteBits(2, 2)
                            .WriteBits(3, character.GetSprites().PrimarySprite)
                            .WriteBits(3, character.GetSprites().SecondarySprite)
                            .WriteBits(1, character.GetUpdateFlags().IsUpdateRequired() ? 1 : 0);
                    }
                    else
                    {
                        character.GetStreamWriter()
                            .WriteBits(1, 1)
                            .WriteBits(2, 1)
                            .WriteBits(3, character.GetSprites().PrimarySprite)
                            .WriteBits(1, character.GetUpdateFlags().IsUpdateRequired() ? 1 : 0);
                    }
                }
            }
        }
        #endregion Methods
    }
}
